<template>
  <div class="form-view-demo-wrapper">
    <div class="component-example">
      <label class="example-title">使用示例</label>
      <div class="example">
        <form-view
          :items="formItem"
          :addForm="formData"
          :uploadConfig="uploadConfig"
          :editorConfig="editorConfig"
          labelWidth="300px"
          ref="formViewRef"
          :predefineColors="predefineColors"
          :showAlpha="true"
          :is-inline="true"
          :collapseTags="true"
          :filterable="true"
          @on-autocomplete-query-search="autocompleteQuerySearch"
          @onSuccess="onSuccess"
          @onError="onError"
        >
          <template v-slot:custom="{ item }">
            <el-tag v-if="item.field === 'custom1'" type="success">
              自定义
            </el-tag>
            <el-rate
              v-else-if="item.field === 'custom2'"
              v-model="formData[item.field]"
            ></el-rate>
          </template>
        </form-view>
        <div style="text-align: center; padding-bottom: 10px">
          <el-button size="small" type="danger" plain @click="resetForm"
            >重置</el-button
          >
          <el-button size="small" type="primary" plain @click="lookFormData"
            >查看</el-button
          >
          <el-button size="small" type="primary" plain @click="fileUpload"
            >文件上传</el-button
          >
        </div>
        <el-dialog :visible.sync="dialogVisible" title="查看">
          <div>
            <p v-for="(item, key, index) in formData" :key="index">
              {{ key }} : {{ item }}
            </p>
          </div>
        </el-dialog>
      </div>
    </div>
    <div class="component-document">
      <div class="import-property">
        <label class="prop-title">输入属性</label>
        <ul class="prop-lists">
          <li class="prop-item" v-for="(item, index) in formProps" :key="index">
            <label class="prop-name">{{ item.name }}：</label>
            <div class="prop-desc">
              <span> {{ item.desc }}</span>
              <div
                class="sub-element-lists"
                v-if="item.lists && item.lists.length !== 0"
              >
                <ul class="sub-lists">
                  <li class="sub-item" v-for="(op, i) in item.lists" :key="i">
                    <label class="sub-prop-name">{{ op.name }}：</label>
                    <span class="sub-prop-value">{{ op.desc }}</span>
                  </li>
                </ul>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="output-method">
        <label class="prop-title">输出方法</label>
        <ul class="prop-lists">
          <li
            class="prop-item"
            v-for="(item, index) in formMethods"
            :key="index"
          >
            <label class="prop-name">{{ item.name }}：</label>
            <span class="prop-desc">{{ item.desc }}</span>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "FormViewDemo",
  data() {
    return {
      urls: {
        getFormViewDataUrl: "./static/json/from-view.json",
      },
      // form表单
      formData: {}, // 表单数据对象
      formItem: [], // 表单的每一项数据
      predefineColors: ["#409EFF", "#67C23A", "#E6A23C", "#F56C6C", "#909399"], // 预定义颜色
      dialogVisible: false,
      uploadConfig: {
        action: remoteUrl + "/demo/test/file/upload",
        headers: {},
        name: "file",
        limit: 5,
        drag: false,
        listType: "picture-card",
        slotContent: "请上传",
      },
      editorConfig: {
        fontNames: ["宋体", "黑体", "微软雅黑", "Arial", "Tahoma", "Verdana"],
      },
      editorContent: "请输入",

      // form表单的属性
      formProps: [
        {
          name: "items",
          desc: "默认值：[]。表单的每一项",
          lists: [
            { name: "header", desc: "显示的中文名称" },
            { name: "field", desc: "字段名称" },
            { name: "type", desc: "控件类型" },
            {
              name: "hidden",
              desc:
                "是否隐藏，例如id需要发给后台，但是不需要显示到界面上，可以设置为true",
            },
            { name: "disabled", desc: "是否禁止输入" },
            { name: "placeholder", desc: "输入框占位符" },
            {
              name: "rule",
              desc:
                "是否是必填项，可以设置规则验证等，如果已传基础配置项中rules参数，则此规则失效，优先遵循所传的rules规则",
            },
            {
              name: "option",
              desc:
                "默认值：[]，如果是下拉菜单等，需要将下拉菜单的选项写在此处，元素格式一般为{label: xx,value: xx}",
            },
            { name: "width", desc: "自定义表单控件的宽度" },
          ],
        },
        {
          name: "addForm",
          desc:
            "默认值：{}，表单的数据对象，键为items中每一项的field值，值为字符串或数组（items中type值为checkbox(多选框)、multiSelect(多选下拉框)、daterange(年月日范围)、datetimerange(年月日时间范围)、selectCascader(级联选择下拉菜单)和upload(上传)的值为数组，其他均为字符串）",
        },
        { name: "rules", desc: "默认值：Object。表单校验规则。" },
        { name: "isInline", desc: "默认值：false。是否开启行内表单域。" },
        {
          name: "position",
          desc:
            "默认值：right。可选值为 top、left、right，当设为 top 时标签会置于表单域的顶部，left、right是对齐方向。",
        },
        {
          name: "formSize",
          desc:
            "默认值：small。用于控制该表单内组件的尺寸 medium 中等/ small 小/ mini 迷你。",
        },
        { name: "labelWidth", desc: "默认值：auto。中文描述文字的宽度。" },
        { name: "valueWidth", desc: "默认值：200px。input输入框的宽。" },
        {
          name: "collapseTags",
          desc: "默认值：false。多选下拉框多选时是否将选中值按文字的形式展示。",
        },
        {
          name: "filterable",
          desc: "默认值：false。下拉框、多选下拉框、级联框可搜索。",
        },
        {
          name: "showAlpha",
          desc: "默认值：false。颜色选择器是否是否支持透明度选择。",
        },
        { name: "predefineColors", desc: "默认值：[]。颜色选择器预定义颜色。" },
        {
          name: "uploadConfig",
          desc: "默认值：{}。文件上传配置",
          lists: [
            { name: "action", desc: "String，必选参数，上传的服务器地址" },
            { name: "headers", desc: "Object，设置上传的请求头部" },
            {
              name: "multiple",
              desc: "Boolean，默认值：true，是否支持多选文件",
            },
            { name: "data", desc: "Object，上传时附带的额外参数" },
            { name: "name", desc: "String，上传的文件字段名" },
            {
              name: "withCredentials",
              desc: "Boolean，默认值：false，支持发送 cookie 凭证信息",
            },
            {
              name: "showFileList",
              desc: "Boolean，默认值：true，是否显示已上传文件列表",
            },
            { name: "drag", desc: "Boolean，默认值：false，是否启用拖拽上传" },
            {
              name: "accept",
              desc:
                "String，接受上传的文件类型，不设置则可以接受所有可上传的文件类型，若想添加限制则有两种方法1.文件扩展名，2.MIME类型。例：.pdf(只接受pdf文件)、image/*(任何图像文件)",
            },
            {
              name: "listType",
              desc:
                "String，默认值：text，文件列表的类型，可选值为text/picture/picture-card",
            },
            {
              name: "autoUpload",
              desc: "Boolean，默认值：false，是否在选取文件后立即进行上传",
            },
            { name: "disabled", desc: "Boolean，默认值：false，是否禁用" },
            { name: "limit", desc: "Number，默认值：10，最大允许上传个数" },
            {
              name: "btnTitle",
              desc: "String，默认值：点击上传，按钮自定义文字",
            },
            { name: "slotContent", desc: "String，提示说明文字" },
          ],
        },
        {
          name: "editorConfig",
          desc: "默认值：{}。富文本编辑器配置（可不传）",
          lists: [
            { name: "menus", desc: "Array，富文本的菜单项" },
            { name: "fontNames", desc: "Array，可选择的字体" },
            { name: "colors", desc: "Array，可选择的颜色" },
            { name: "zIndex", desc: "Number，默认值：1000，编辑区域的权重" },
            {
              name: "debug",
              desc:
                "Boolean，默认值：true，是否开启 debug 模式（debug 模式下错误会 throw error 形式抛出）",
            },
            {
              name: "pasteFilterStyle",
              desc: "Boolean，默认值：true，粘贴是否过滤样式",
            },
            {
              name: "pasteIgnoreImg",
              desc: "Boolean，默认值：false，粘贴内容时，忽略图片",
            },
            {
              name: "showLinkImg",
              desc: "Boolean，默认值：true，是否显示添加网络图片的 tab",
            },
            {
              name: "uploadImgMaxSize",
              desc: "Number，默认值：5 * 1024 * 1024，默认上传图片 max size: M",
            },
            {
              name: "uploadImgMaxLength",
              desc: "Number，默认值：10000，配置一次最多上传几个图片",
            },
            {
              name: "uploadImgShowBase64",
              desc: "Boolean，默认值：true，上传图片，是否显示 base64 格式",
            },
            {
              name: "uploadImgServer",
              desc:
                "Boolean，上传图片，server 地址（如果有值，则 base64 格式的配置则失效）",
            },
            { name: "uploadFileName", desc: "String，自定义配置 filename" },
            {
              name: "uploadImgParams",
              desc: "Object，上传图片的自定义参数 如token等",
            },
            {
              name: "uploadImgHeaders",
              desc: "Object，上传图片的自定义header 如Accept等",
            },
            {
              name: "withCredentials",
              desc:
                "Boolean，是否使用类似cookies,authorization headers(头部授权)或者TLS客户端证书这一类资格证书来创建一个跨站点访问控制（cross-site Access-Control）请求，在同一个站点下使用withCredentials属性是无效的。",
            },
            {
              name: "uploadImgTimeout",
              desc: "Number，默认值：10000，自定义上传图片超时时间 ms",
            },
          ],
        },
      ],
      // 表单输出方法
      formMethods: [
        {
          name: "on-autocomplete-query-search",
          desc: "参数：queryString, cb, item。返回输入建议的方法。",
        },
        {
          name: "on-autocomplete-select",
          desc: "参数：{value, item}。选择建议的回调函数。",
        },
        { name: "on-change-number", desc: "参数：number。改变数字时触发。" },
        { name: "on-change-date", desc: "参数：date。改变日期时触发。" },
        { name: "on-change-year", desc: "参数：year。改变年时触发。" },
        { name: "on-change-month", desc: "参数：month。改变月时触发。" },
        {
          name: "on-change-date-time-range",
          desc: "参数：month。改变日期时间时触发。",
        },
        { name: "on-change-date-range", desc: "参数：month。改变日期时触发。" },
        {
          name: "on-change-option",
          desc: "参数：{item,label,value}。改变下拉选中项时触发。",
        },
        {
          name: "on-edit-select-change",
          desc: "参数：item。改变可编辑的下拉菜单时触发。",
        },
        {
          name: "on-change-multi-option",
          desc: "参数：{value, item}。改变多选下拉框时触发。",
        },
        {
          name: "on-cascader-select-change",
          desc: "参数：item，级联下拉框当选中节点变化时触发。",
        },
        {
          name: "on-cascader-item-change",
          desc: "参数：{label, item}，级联下拉框当展开节点发生变化时触发。",
        },
        { name: "on-change-radio", desc: "参数：label。改变单选框时触发。" },
        { name: "on-checked-change", desc: "参数：value。改变多选框时触发。" },
        {
          name: "on-change-color-picker",
          desc: "参数：value。当颜色选择器绑定的值变化时触发。",
        },
        {
          name: "on-active-change-color-picker",
          desc: "参数：value。颜色选择器面板中当前显示的颜色发生改变时触发。",
        },
        {
          name: "on-preview",
          desc: "参数：file。点击文件列表中已上传的文件时的钩子。",
        },
        {
          name: "on-remove",
          desc: "参数：{file, fileList}。文件列表移除文件时的钩子。",
        },
        {
          name: "on-success",
          desc: "参数：{response, file, fileList}。文件上传成功时的钩子。",
        },
        {
          name: "on-error",
          desc: "参数：{err, file, fileList}。文件上传失败时的钩子。",
        },
        {
          name: "on-progress",
          desc: "参数：{event, file, fileList}。文件上传时的钩子。",
        },
        {
          name: "on-change",
          desc:
            "参数：{file, fileList}。文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用。",
        },
        {
          name: "before-upload",
          desc:
            "参数：file。上传文件之前的钩子，参数为上传的文件，若返回 false 或者返回 Promise 且被 reject，则停止上传。",
        },
        {
          name: "before-remove",
          desc:
            "参数：{file, fileList}。删除文件之前的钩子，参数为上传的文件和文件列表，若返回 false 或者返回 Promise 且被 reject，则停止删除。",
        },
        {
          name: "resetFields",
          desc: "使用方法：this.$refs.XXX.resetFields()。重置表单内容时调用。",
        },
        {
          name: "validate",
          desc:
            "使用方法：this.$refs.XXX.validate().then(res => {}).catch(err => {})。提交表单时的规则校验，验证成功可在.then函数中继续之后操作。",
        },
        {
          name: "submit",
          desc: "使用方法：this.$refs.XXX.submit()。手动上传文件时调用。",
        },
        { name: "富文本输出方法", desc: "详见富文本编辑器中输出方法" },
      ],
    };
  },
  mounted() {
    this.getFormViewData();
  },
  methods: {
    // 获取form数据
    getFormViewData() {
      this.httpRequest(
        "get",
        this.urls.getFormViewDataUrl,
        {},
        { hideSuccessTip: true, dataKey: "cols" }
      ).then((res) => {
        this.formItem = this.getPatternHeader(res, {psw: 'password', email: 'email'});
        console.log(this.formItem);
        let info = {};
        this.formItem.forEach((d) => {
          if (
            d.type === "checkbox" ||
            d.type === "multiSelect" ||
            d.type === "datetimerange" ||
            d.type === "daterange" ||
            d.type === "selectCascader"
          ) {
            info[d.field] = [];
          } else if (d.type === "upload") {
            info[d.field] = [
              {
                url:
                  "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
              },
            ];
          } else if (d.type === "editor") {
            info[d.field] = "请编辑...";
          } else {
            info[d.field] = null;
          }
        });
        this.formData = JSON.parse(JSON.stringify(info));
        this.resetForm();
      });
    },
    // 重置表单内容
    resetForm() {
      this.$refs.formViewRef.resetFields();
    },
    // 查看表单内容
    lookFormData() {
      // 校验输入框内容是否通过，通过则在.then回调中继续下一步操作
      this.$refs.formViewRef
        .validate()
        .then((res) => {
          this.dialogVisible = true;
        })
        .catch((err) => {
          return false;
        });
    },
    // 文件上传
    fileUpload() {
      this.$refs.formViewRef
        .validate()
        .then((res) => {
          let formData = JSON.parse(JSON.stringify(this.formData));
          delete formData.upload;
          this.$set(this.uploadConfig, "data", formData);
          // 上传文件
          this.$nextTick(() => {
            this.$refs.formViewRef.submit();
          });
        })
        .catch((err) => {
          return false;
        });
    },
    onSuccess() {
      this.$message.success("文件上传成功！");
    },
    onError() {
      this.$message.error("文件上传失败！");
    },
    // 输入建议
    autocompleteQuerySearch(queryString, cb, item) {
      let restaurants = [
        {
          value: "樱花食堂（凌空店）",
          address: "上海市长宁区金钟路968号15楼15-105室",
        },
        { value: "壹分米客家传统调制米粉(天山店)", address: "天山西路428号" },
        {
          value: "福荣祥烧腊（平溪路店）",
          address: "上海市长宁区协和路福泉路255弄57-73号",
        },
        {
          value: "速记黄焖鸡米饭",
          address: "上海市长宁区北新泾街道金钟路180号1层01号摊位",
        },
        { value: "红辣椒麻辣烫", address: "上海市长宁区天山西路492号" },
        {
          value: "(小杨生煎)西郊百联餐厅",
          address: "长宁区仙霞西路88号百联2楼",
        },
        { value: "阳阳麻辣烫", address: "天山西路389号" },
        {
          value: "南拳妈妈龙虾盖浇饭",
          address: "普陀区金沙江路1699号鑫乐惠美食广场A13",
        },
      ];
      let results = queryString
        ? restaurants.filter(this.createFilter(queryString))
        : restaurants;
      cb(results);
    },
    createFilter(queryString) {
      return (restaurant) =>
        restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
    },
  },
};
</script>

<style lang="scss" scoped>
.form-view-demo-wrapper {
  width: 100%;
  height: 100%;
}
</style>
